package com.pai4j.user.service.approval;

import com.pai4j.common.enums.AccountRelationStatusEnum;
import com.pai4j.common.enums.GroupInvitationStatusEnum;
import com.pai4j.common.enums.PendingApprovalTypeEnum;
import com.pai4j.domain.vo.response.PendingApprovalResponseVO;
import com.pai4j.user.repository.dao.IAccountRelationDAO;
import com.pai4j.user.repository.dao.IGroupJoinApplicationDAO;
import com.pai4j.user.repository.dao.IPendingApprovalDAO;
import com.pai4j.user.repository.entity.AccountRelationEntity;
import com.pai4j.user.repository.entity.GroupJoinApplicationEntity;
import com.pai4j.user.repository.entity.PendingApprovalEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 统一待审核服务
 * 
 * 核心功能：
 * 1. 提供统一的待审核查询接口（支持多类型聚合查询）
 * 2. 提供统一的标记已读接口
 * 3. 提供统一的未读数统计接口
 * 4. 确保统一待审核表和业务表的强一致性
 */
@Slf4j
@Service
public class PendingApprovalService {

    @Autowired
    private IPendingApprovalDAO pendingApprovalDAO;

    @Autowired
    private IAccountRelationDAO accountRelationDAO;

    @Autowired
    private IGroupJoinApplicationDAO groupJoinApplicationDAO;
    
    @Autowired
    private com.pai4j.user.repository.dao.IGroupInvitationDAO groupInvitationDAO;

    /**
     * 查询待审核列表
     * 
     * @param approverAccount 审批人账号
     * @param approvalType 审批类型，null则查询所有类型
     * @param approvalStatus 审批状态（1=待处理）
     * @return 待审核列表
     */
    public List<PendingApprovalResponseVO> listPendingApprovals(String approverAccount, Integer approvalType, Integer approvalStatus) {
        log.info("查询待审核列表：approverAccount={}, approvalType={}, approvalStatus={}", approverAccount, approvalType, approvalStatus);
        
        List<PendingApprovalEntity> entities = pendingApprovalDAO.findPendingApprovals(approverAccount, approvalType, approvalStatus);
        
        List<PendingApprovalResponseVO> result = new ArrayList<>();
        for (PendingApprovalEntity entity : entities) {
            PendingApprovalResponseVO vo = convertToVO(entity);
            result.add(vo);
        }
        
        log.info("查询到 {} 条待审核记录", result.size());
        return result;
    }

    /**
     * 查询未读待审核列表
     * 
     * @param approverAccount 审批人账号
     * @param approvalType 审批类型，null则查询所有类型
     * @param approvalStatus 审批状态（1=待处理）
     * @return 未读待审核列表
     */
    public List<PendingApprovalResponseVO> listUnreadPendingApprovals(String approverAccount, Integer approvalType, Integer approvalStatus) {
        log.info("查询未读待审核列表：approverAccount={}, approvalType={}, approvalStatus={}", approverAccount, approvalType, approvalStatus);
        
        List<PendingApprovalEntity> entities = pendingApprovalDAO.findUnreadPendingApprovals(approverAccount, approvalType, approvalStatus);
        
        List<PendingApprovalResponseVO> result = new ArrayList<>();
        for (PendingApprovalEntity entity : entities) {
            PendingApprovalResponseVO vo = convertToVO(entity);
            result.add(vo);
        }
        
        log.info("查询到 {} 条未读待审核记录", result.size());
        return result;
    }

    /**
     * 统计未读待审核数量
     * 
     * @param approverAccount 审批人账号
     * @param approvalType 审批类型，null则统计所有类型
     * @param approvalStatus 审批状态（1=待处理）
     * @return 未读数量
     */
    public Long countUnreadPendingApprovals(String approverAccount, Integer approvalType, Integer approvalStatus) {
        log.info("统计未读待审核数量：approverAccount={}, approvalType={}, approvalStatus={}", approverAccount, approvalType, approvalStatus);
        
        Long count = pendingApprovalDAO.countUnreadPendingApprovals(approverAccount, approvalType, approvalStatus);
        
        log.info("未读待审核数量：{}", count);
        return count;
    }

    /**
     * 标记待审核为已读（强一致性）
     * 同时更新统一待审核表和对应的业务表
     * 
     * @param approverAccount 审批人账号
     * @param approvalType 审批类型，null则标记所有类型
     * @param approvalStatus 审批状态（1=待处理）
     * @return 标记数量
     */
    @Transactional(rollbackFor = Exception.class)
    public int markApprovalsAsRead(String approverAccount, Integer approvalType, Integer approvalStatus) {
        log.info("标记待审核为已读：approverAccount={}, approvalType={}, approvalStatus={}", approverAccount, approvalType, approvalStatus);
        
        int count;
        
        // 1. 更新统一待审核表
        if (approvalType == null) {
            // 标记所有类型
            count = pendingApprovalDAO.markAllApprovalsAsRead(approverAccount, approvalStatus);
            
            // 2. 同步更新各业务表
            syncMarkReadToAllBizTables(approverAccount, approvalStatus);
        } else {
            // 标记指定类型
            count = pendingApprovalDAO.markApprovalsAsReadByType(approverAccount, approvalType, approvalStatus);
            
            // 2. 同步更新对应业务表
            syncMarkReadToBizTable(approverAccount, approvalType, approvalStatus);
        }
        
        log.info("成功标记 {} 条待审核记录为已读（统一表+业务表已同步）", count);
        return count;
    }

    /**
     * 同步标记所有业务表为已读
     */
    private void syncMarkReadToAllBizTables(String approverAccount, Integer approvalStatus) {
        // 标记好友申请
        syncMarkReadToBizTable(approverAccount, PendingApprovalTypeEnum.FRIEND_REQUEST.getType(), approvalStatus);
        
        // 标记加群申请
        syncMarkReadToBizTable(approverAccount, PendingApprovalTypeEnum.GROUP_JOIN_REQUEST.getType(), approvalStatus);
        
        // 标记群邀请
        syncMarkReadToBizTable(approverAccount, PendingApprovalTypeEnum.GROUP_INVITATION.getType(), approvalStatus);
        
        // 后续可扩展其他类型
    }

    /**
     * 同步标记指定业务表为已读
     */
    private void syncMarkReadToBizTable(String approverAccount, Integer approvalType, Integer approvalStatus) {
        PendingApprovalTypeEnum typeEnum = PendingApprovalTypeEnum.getByType(approvalType);
        if (typeEnum == null) {
            log.warn("未知的待审核类型：{}", approvalType);
            return;
        }
        
        switch (typeEnum) {
            case FRIEND_REQUEST:
                // 同步更新好友申请表
                int friendCount = accountRelationDAO.markPendingRelationsAsRead(
                        approverAccount,
                        com.pai4j.common.enums.AccountRelationTypeEnum.USER_USER.getType(),
                        AccountRelationStatusEnum.WAIT_CONFIRMED.getStatus()
                );
                log.info("同步标记好友申请表已读：{} 条", friendCount);
                break;
                
            case GROUP_JOIN_REQUEST:
                // 加群申请的approverAccount需要转换为groupPaiId
                // 注意：这里需要查询该用户管理的所有群，然后批量更新
                // 为简化实现，这里通过查询统一表获取相关群ID
                List<PendingApprovalEntity> groupApprovals = pendingApprovalDAO.findPendingApprovals(
                        approverAccount,
                        PendingApprovalTypeEnum.GROUP_JOIN_REQUEST.getType(),
                        approvalStatus
                );
                
                for (PendingApprovalEntity approval : groupApprovals) {
                    int groupCount = groupJoinApplicationDAO.markApplicationsAsRead(
                            approval.getTargetId(), // groupPaiId
                            approvalStatus
                    );
                    log.info("同步标记群 {} 的加群申请表已读：{} 条", approval.getTargetId(), groupCount);
                }
                break;
            
            case GROUP_INVITATION:
                // 群邀请的approverAccount就是被邀请人（inviteeAccount）
                // 查询该用户收到的所有待处理群邀请
                List<PendingApprovalEntity> invitationApprovals = pendingApprovalDAO.findPendingApprovals(
                        approverAccount,
                        PendingApprovalTypeEnum.GROUP_INVITATION.getType(),
                        approvalStatus
                );
                
                // 同步更新群邀请表（暂不实现，群邀请表没有is_read字段）
                // 群邀请通过统一待审核表的is_read字段来判断是否已读
                log.info("群邀请已读状态由统一待审核表管理，业务表无需同步：{} 条", invitationApprovals.size());
                break;
                
            default:
                log.warn("待审核类型 {} 暂不支持同步业务表", typeEnum.getTypeName());
                break;
        }
    }

    /**
     * 创建待审核记录（供业务表插入时调用，保证强一致性）
     * 
     * @param approvalType 审批类型
     * @param bizRecordId 业务记录ID
     * @param applicantAccount 申请人账号
     * @param approverAccount 审批人账号
     * @param targetId 关联目标ID
     * @param applicationMessage 申请留言
     * @param approvalStatus 审批状态
     * @param expireTime 过期时间
     * @return 创建的待审核记录
     */
    @Transactional(rollbackFor = Exception.class)
    public PendingApprovalEntity createPendingApproval(
            Integer approvalType,
            Long bizRecordId,
            String applicantAccount,
            String approverAccount,
            String targetId,
            String applicationMessage,
            Integer approvalStatus,
            Date expireTime) {
        return createPendingApproval(approvalType, bizRecordId, applicantAccount, approverAccount, 
                targetId, applicationMessage, approvalStatus, expireTime, null);
    }

    /**
     * 创建待审核记录（支持推荐人信息）
     * 
     * @param approvalType 审批类型
     * @param bizRecordId 业务记录ID
     * @param applicantAccount 申请人账号
     * @param approverAccount 审批人账号
     * @param targetId 关联目标ID
     * @param applicationMessage 申请留言
     * @param approvalStatus 审批状态
     * @param expireTime 过期时间
     * @param recommenderAccount 推荐人账号（可选）
     * @return 创建的待审核记录
     */
    @Transactional(rollbackFor = Exception.class)
    public PendingApprovalEntity createPendingApproval(
            Integer approvalType,
            Long bizRecordId,
            String applicantAccount,
            String approverAccount,
            String targetId,
            String applicationMessage,
            Integer approvalStatus,
            Date expireTime,
            String recommenderAccount) {
        
        log.info("创建待审核记录：approvalType={}, bizRecordId={}, applicantAccount={}, approverAccount={}, recommenderAccount={}", 
                approvalType, bizRecordId, applicantAccount, approverAccount, recommenderAccount);
        
        PendingApprovalEntity entity = new PendingApprovalEntity();
        entity.setApprovalType(approvalType);
        entity.setBizRecordId(bizRecordId);
        entity.setApplicantAccount(applicantAccount);
        entity.setApproverAccount(approverAccount);
        entity.setTargetId(targetId);
        entity.setApplicationMessage(applicationMessage);
        entity.setApprovalStatus(approvalStatus);
        entity.setIsRead(false);
        entity.setExpireTime(expireTime);
        entity.setRecommenderAccount(recommenderAccount);
        entity.setCreateDate(new Date());
        entity.setUpdateDate(new Date());
        
        PendingApprovalEntity saved = pendingApprovalDAO.save(entity);
        log.info("待审核记录创建成功：id={}, recommender={}", saved.getId(), recommenderAccount);
        
        return saved;
    }

    /**
     * 更新待审核状态（供业务表更新时调用，保证强一致性）
     * 
     * @param approvalType 审批类型
     * @param bizRecordId 业务记录ID
     * @param approvalStatus 新的审批状态
     * @param handledByAccount 处理人账号
     * @param approvalRemark 审批意见
     * @return 更新数量
     */
    @Transactional(rollbackFor = Exception.class)
    public int updateApprovalStatus(
            Integer approvalType,
            Long bizRecordId,
            Integer approvalStatus,
            String handledByAccount,
            String approvalRemark) {
        
        log.info("更新待审核状态：approvalType={}, bizRecordId={}, approvalStatus={}, handledByAccount={}", 
                approvalType, bizRecordId, approvalStatus, handledByAccount);
        
        int count = pendingApprovalDAO.updateApprovalStatus(
                approvalType, bizRecordId, approvalStatus, handledByAccount, approvalRemark);
        
        log.info("待审核状态更新成功：更新 {} 条记录", count);
        return count;
    }

    /**
     * Entity转VO
     */
    private PendingApprovalResponseVO convertToVO(PendingApprovalEntity entity) {
        PendingApprovalResponseVO vo = new PendingApprovalResponseVO();
        BeanUtils.copyProperties(entity, vo);
        
        // 设置类型名称
        PendingApprovalTypeEnum typeEnum = PendingApprovalTypeEnum.getByType(entity.getApprovalType());
        if (typeEnum != null) {
            vo.setApprovalTypeName(typeEnum.getTypeName());
        }
        
        // 设置状态名称（简化处理，实际可能需要根据类型判断）
        GroupInvitationStatusEnum statusEnum = GroupInvitationStatusEnum.getByStatus(entity.getApprovalStatus());
        if (statusEnum != null) {
            vo.setApprovalStatusName(statusEnum.getStatusName());
        }
        
        // TODO: 可以在这里填充申请人昵称、头像等信息（通过调用用户服务）
        
        return vo;
    }
}
